package org.springframework.boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.BindResult;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.ResourcePropertySource;
import org.springframework.util.ReflectionUtils;

import java.io.IOException;
import java.lang.reflect.Field;

/**
 * 将配置文件的内容绑定到类或对象的指定的属性上
 */
public class Step6 {
    // 绑定 spring.main 前缀的 key value 至 SpringApplication, 请通过 debug 查看
    public static void main(String[] args) throws IOException, NoSuchFieldException {
        SpringApplication application = new SpringApplication();
        ApplicationEnvironment env = new ApplicationEnvironment();
        env.getPropertySources().addLast(new ResourcePropertySource("step4", new ClassPathResource("step4.properties")));
        env.getPropertySources().addLast(new ResourcePropertySource("step6", new ClassPathResource("step6.properties")));

        System.out.println("################### 绑定到为上返回指定类型的对象 ####################");
        User user = Binder.get(env).bind("user", User.class).get();
        System.out.println(user);
        System.out.println("================== 绑定到已经存在对象 ====================");

        User user2 = new User();
        Binder.get(env).bind("user", Bindable.ofInstance(user2));
        System.out.println(user2);
        System.out.println("%%%%%%%%%%%%%%%%%% 绑定到application 之前 %%%%%%%%%%%%%%%%%%%%%%%%%%");
        System.out.println(application);
        Field lazyInitialization = ReflectionUtils.findField(SpringApplication.class,"lazyInitialization");
        lazyInitialization.setAccessible(true);
        Object lazyInitializationValue = ReflectionUtils.getField(lazyInitialization, application);
        System.out.println("lazyInitializationValue : " + lazyInitializationValue);
        Field bannerMode = ReflectionUtils.findField(SpringApplication.class,"bannerMode");
        bannerMode.setAccessible(true);
        Object bannerModeValue = ReflectionUtils.getField(bannerMode, application);
        System.out.println("bannerModeValue : " + bannerModeValue);
        //application
        Binder.get(env).bind("spring.main", Bindable.ofInstance(application));
        System.out.println("**************** 绑定到application 之后 *******************");
        System.out.println(application);
        Field lazyInitialization1 = ReflectionUtils.findField(SpringApplication.class,"lazyInitialization");
        lazyInitialization1.setAccessible(true);
        Object lazyInitializationValue1 = ReflectionUtils.getField(lazyInitialization1, application);
        System.out.println("lazyInitializationValue1 : " + lazyInitializationValue1);
        Field bannerMode1 = ReflectionUtils.findField(SpringApplication.class,"bannerMode");
        bannerMode1.setAccessible(true);
        Object bannerModeValue1 = ReflectionUtils.getField(bannerMode1, application);
        System.out.println("bannerModeValue1 : " + bannerModeValue1);
    }

    static class User {
        private String firstName;
        private String middleName;
        private String lastName;
        public String getFirstName() {
            return firstName;
        }
        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }
        public String getMiddleName() {
            return middleName;
        }
        public void setMiddleName(String middleName) {
            this.middleName = middleName;
        }
        public String getLastName() {
            return lastName;
        }
        public void setLastName(String lastName) {
            this.lastName = lastName;
        }
        @Override
        public String toString() {
            return "User{" +
                   "firstName='" + firstName + '\'' +
                   ", middleName='" + middleName + '\'' +
                   ", lastName='" + lastName + '\'' +
                   '}';
        }
    }
}
